﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Spring.Transaction.Interceptor;

using BOSS.Framework;
using BOSS.Domain.Security;
using BOSS.Dao.Security;
using BOSS.Service.Security;

namespace BOSS.Service.Implements.Security
{
    /// <summary>
    /// 角色服务
    /// </summary>
    public class RoleService : EntityService<Role, int, IRoleDao>, IRoleService
    {
        /// <summary>
        /// 获取 / 设置 角色权限设置 DAO
        /// </summary>
        public IRolePrivilegeSettingDao RolePrivilegeSettingDao { get; set; }

        /// <summary>
        /// 获取 / 设置 安全服务
        /// </summary>
        public ISecurityService SecurityService { get; set; }

        #region IGroupService 成员

        /// <summary>
        /// 查找指派给指定角色的权限组（静态权限）
        /// </summary>
        /// <param name="role"></param>
        /// <returns></returns>
        public PrivilegeGroup GetAssignedPrivileges(Role role)
        {
            Check.Require(role != null);

            return this.RolePrivilegeSettingDao.SelectByRole(role);
        }

        /// <summary>
        /// 设置指派给指定角色的权限组
        /// </summary>
        /// <param name="role"></param>
        /// <param name="privileges"></param>
        [Transaction(ReadOnly = false)]
        public void SetAssignedPrivileges(Role role, PrivilegeGroup privileges)
        {
            Check.Require(role != null);
            Check.Require(privileges != null);

            PrivilegeGroup current = this.RolePrivilegeSettingDao.SelectByRole(role);
            IList<Privilege> forInsert = new List<Privilege>();
            IList<Privilege> forUpdate = new List<Privilege>();

            // 计算新增、修改、删除三类操作所涉及的权限
            foreach (Privilege privilege in privileges.Privileges)
            {
                Privilege found = current.Privileges.SingleOrDefault(p => p.Name.Equals(privilege.Name, StringComparison.OrdinalIgnoreCase));
                if (found == null)
                {
                    if (privilege.Permission != PermissionType.INHERIT)
                    {
                        forInsert.Add(privilege);
                    }
                }
                else
                {
                    if (privilege.Permission != PermissionType.INHERIT)
                    {
                        if (found.Permission != privilege.Permission)
                        {
                            forUpdate.Add(privilege);
                        }
                        current.Privileges.Remove(found);
                    }
                }
            }

            // 执行更新
            bool dirty = false;
            foreach (Privilege privilege in current.Privileges)
            {
                dirty = true;
                this.RolePrivilegeSettingDao.Delete(role, privilege);
            }
            foreach (Privilege privilege in forUpdate)
            {
                dirty = true;
                this.RolePrivilegeSettingDao.Update(role, privilege);
            }
            foreach (Privilege privilege in forInsert)
            {
                dirty = true;
                this.RolePrivilegeSettingDao.Insert(role, privilege);
            }

            if (dirty)
            {
                this.SecurityService.FlushRuntimePrivileges();
            }
        }

        /// <summary>
        /// 查找拥有指定权限的角色集合
        /// </summary>
        /// <param name="privilegeName"></param>
        /// <returns></returns>
        public IDictionary<Role, PermissionType> SelectPermissions(string privilegeName)
        {
            Check.Require(!string.IsNullOrEmpty(privilegeName));

            IDictionary<Role, PermissionType> permissions = new Dictionary<Role, PermissionType>();
            IList<RolePrivilegeSetting> privilegeSettings = this.RolePrivilegeSettingDao.SelectByName(privilegeName);
            foreach (RolePrivilegeSetting privilegeSetting in privilegeSettings)
            {
                if (privilegeSetting.Permission != PermissionType.INHERIT)
                {
                    permissions[privilegeSetting.Role] = privilegeSetting.Permission;
                }
            }
            return permissions;
        }

        #endregion
    }
}
